<script setup>
import { ElMessageBox } from "element-plus";
import { ref, onMounted, getCurrentInstance } from "vue";
import { useRouter } from "vue-router";
import { menuStore } from "../utils/store";
import {get} from '../api/http'

const chatMsg = ref('')
const instance = getCurrentInstance()
var socket = null;
const newFlag = ref(true);
var connectFlag = false;
const messageList = ref([])
const router = useRouter()
var lockReconnect = false; //避免ws重复连接
var ws = null; // 判断当前浏览器是否支持WebSocket
var wsUrl = null;
var config = {}
var msgId = 0

//心跳检测
var heartCheck = {
    timeout: 10000, //9分钟发一次心跳
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function() {
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function() {
        var self = this;
        this.timeoutObj = setTimeout(function() {
            //这里发送一个心跳，后端收到后，返回一个心跳消息，
            //onmessage拿到返回的心跳就说明连接正常
            ws.send("[$check$]");
            self.serverTimeoutObj = setTimeout(function() { //如果超过一定时间还没重置，说明后端主动断开了
                console.log("try=close")
                ws.close(); 
            }, self.timeout)
        }, this.timeout)
    }
}


const sendMessage = (message) => {
  ws.send(message);
};

window.onbeforeunload = function() {
    ws.close();
}

const submitChat = () => {
  let chatBox = document.getElementById("chatBox");
  sendMessage(chatMsg.value);
  sendSounds();
  newFlag.value = true;
  let chat = {
    text: chatMsg.value,
    type: 'self',
    avatar: 'https://www.devcat.cn/res/img/huhailong.png'
  }
  messageList.value.push(chat);
  chatBox.scrollTo(0, chatBox.scrollHeight);

  instance.refs.textRef.clear()
};

const sendSounds = () => {
  let sendMp3 = new Audio("https://www.devcat.cn/res/mp3/send.mp3");
  sendMp3.play();
};

const socketLink = (set) => {
  config = set;
  wsUrl = config.url;
  createWebSocket(wsUrl); //连接ws
}

const createWebSocket = (url) => {
    try {
        if ('WebSocket' in window) {
            ws = new WebSocket(url, 'echo-protocol');
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(url, 'echo-protocol');
        } else {
            ElMessageBox.alert("您的浏览器不支持websocket")
        }
        initEventHandle();
    } catch (e) {
        reconnect(url);
        console.log(e);
    }
}

const initEventHandle = () => {
    ws.onclose = function() {
        reconnect(wsUrl);
    };
    ws.onerror = function() {
        reconnect(wsUrl);
    };
    ws.onopen = function() {
        heartCheck.reset().start(); //心跳检测重置
        // config.open(ws)
    };
    ws.onmessage = function(e) { //如果获取到消息，心跳检测重置
        heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
        if(e.data == '[$alive$]'){
          return;
        }
        if (newFlag.value) {
          msgId = new Date().getTime();
          messageList.value.push({
            id: msgId,
            text: e.data,
            type: 'gpt',
            avatar: 'https://www.devcat.cn/res/img/gpt.png'
          })
          newFlag.value = false;
        } else {
          messageList.value.find(v=>{return v.id === msgId}).text += e.data;
        }
        chatBox.scrollTo(0, chatBox.scrollHeight);
    };
}

const reconnect = (url) => {
    if (lockReconnect) return;
    lockReconnect = true;
    setTimeout(function() { //没连接上会一直重连，设置延迟避免请求过多
        createWebSocket(url);
        lockReconnect = false;
    }, 2000);
}

const getMenuList = () => {
      get('menu').then(res=>{
          if(res.status){
              let flag = res.data.find(value=>{
                return value.menuRoute == '/chatGpt'
              })
              if(flag==null){
                router.push('/403')
              }
          }else{
              ElMessage({type: 'error', message: res.msg})
          }
      })
  }

onMounted(() => {
  getMenuList()
  console.log(menuStore.menuList)
  socketLink({url:'wss://www.huhailong.vip/ws/gpt'})
  messageList.value.push({
    id: msgId,
    text: 'Hello，我是胡海龙，这是我基于OpenAI搭建的Chat程序，你可以像使用ChatGPT一样来使用它，如何搭建以及源码可以联系我：**hhlworkspace@qq.com**\n - 无需VPN \n - 支持Makrdown格式化 \n\n [本站网址: www.devcat.cn](https://www.devcat.cn)',
    type: 'gpt',
    avatar: 'https://www.devcat.cn/res/img/gpt.png'
  })
  
});
</script>
<template>
    <main v-blog-title data-title="ChatGPT">
        <el-row style="width:100%" justify="center">
            <el-col :lg="18" :md="22" :xs="24">
                <div class="chatBox" id="chatBox">
                    <div class="chatItem" v-for="(item,index) in messageList" :key="index">
                        <div class="avatar">
                            <img :src="item.avatar" style="width:35px; height=35px;"/>
                        </div>
                        <div :class="item.type==='gpt'?'message':'myself'">
                            <v-md-preview class="previewPage" :text="item.text"></v-md-preview>
                        </div>
                    </div>
                </div>
                <div class="sendBox">
                    <el-input clearable ref="textRef" @keydown.enter="submitChat" resize="none" class="textarea" type="textarea" v-model="chatMsg" placeholder="输入问题" rows="6"></el-input>
                    <el-button style="margin: 10px 0; width:100px;" type="primary" @click="submitChat">发送</el-button>
                </div>
            </el-col>
        </el-row>
    </main>
</template>
<style scoped>
main{
    margin-top: 10px;
    width: 100%;
    display: flex;
    align-items: center;
    flex-direction: column;
}
.previewPage{
  padding: 5px 0 0 0;
}
.previewPage:deep(.github-markdown-body){
  padding: 0;
}
.chatBox {
  padding: 10px;
  width: clac(100% - 10px);
  height: 450px;
  border-bottom: 1px solid #ddd;
  background-color: #fff;
  overflow-y: auto;
}
.sendBox {
  display: flex;
  flex-direction: column;
  align-items: end;
}
.textarea {
  padding: 10px;
  width: 100%;
}
.sendBox:deep(el-textarea__inner){
    border: none;
    outline: none;
    margin: 0;
    outline: none;
}
.sendBox:deep(.el-textarea){
    margin: 0;
    padding: 0;
    border: none;
    outline: none;

}
.avatar img {
  border-radius: 50%;
  margin-right: 10px;
}
.chatItem {
  display: flex;
  /* align-items: center; */
  margin: 10px 0;
}
.message,.myself {
  font-size: 14px;
  background-color: #f2f3f5;
  padding: 5px 10px 0 10px;
  margin-right: 10px;
  border-radius: 4px;
}
p {
  margin: 5px 0;
}
pre {
  width: calc(100% - 10px);
  display: block;
  background-color: #333;
  color: #fff;
  padding: 5px;
}

button:hover {
  opacity: 0.8;
}
button:active {
  opacity: 1;
}
.myself {
  background-color: #ecf5ff;
  color: #000;
}
h2 {
  font-weight: 400;
  font-family: "Times New Roman", Times, serif;
  color: #777;
}
</style>